package util;

import cn.hutool.core.util.RandomUtil;
import org.apache.commons.lang3.RandomUtils;

import java.math.BigDecimal;

/**
 * @author liule
 * @date 2023/7/13 10:18
 * @Desc : 二倍均值法红包金额算法
 */
public class RedPacketsAlgorithm {
    public static void main(String[] args) {
        // 红包金额
        BigDecimal totalMoney = new BigDecimal(10);
        // 红包的总个数
        int totalPeople = 5;

        // 使用二倍均值法计算
        doubleMeanMethod(totalMoney, totalPeople);
    }

    /**
     * 抢红包算法测试（二倍均值法）
     */
    void grapRedPacket() {
        // 红包金额
        BigDecimal totalMoney = new BigDecimal(10);
        // 红包的总个数
        int totalPeople = 5;

        // 使用二倍均值法计算
        doubleMeanMethod(totalMoney, totalPeople);
    }

    /**
     * 使用二倍均值法抢红包
     * @param totalMoney
     * @param totalPeople
     */
    public static void doubleMeanMethod(BigDecimal totalMoney, int totalPeople) {
        // 判断红包的总金额与总个数
        if(totalMoney.compareTo(BigDecimal.valueOf(0.01)) == -1 || totalPeople < 1){
            return;
        }
        System.out.println("==============开始抢红包==============");

        // 红包剩余金额
        BigDecimal leftMoney = totalMoney;
        // 红包剩余个数
        int leftPeople = totalPeople;
        // 定义变量，验证总金额
        BigDecimal totalAmount = BigDecimal.valueOf(0);
        
        // 循环总人数，开始抢红包（最后一个前红包的用户，不需要计算）
        for (int i = 0; i < totalPeople -1; i++) {
            // 计算随机抢到的金额，随机范围：[1,剩余金额的两倍），左闭右开，单位分
            // 剩余红包金额/剩余红包个数
            // 2：保留两位小数 BigDecimal.ROUND_HALF_UP:四舍五入
            BigDecimal result = leftMoney.divide(BigDecimal.valueOf(leftPeople),2,BigDecimal.ROUND_HALF_UP);
            // 二倍均值法：（m/n）*2，剩余红包金额/剩余红包个数 * 2
            result  =result.multiply(BigDecimal.valueOf(2));
            // 将金钱单位由元转为分
            int limit = (int)(result.doubleValue() * 100);
            // 随机抢到的红包金额，将金钱单位由分转为元
            BigDecimal amount = BigDecimal.valueOf(RandomUtil.randomInt(limit-1) + 1).divide(BigDecimal.valueOf(100),2,BigDecimal.ROUND_HALF_UP);

            // 更新红包金额
            leftMoney = leftMoney.subtract(amount);
            // 更新红包剩余个数：剩余个数 = 剩余个数 -1；
            leftPeople--;
            // 抢到的金额累加
            totalAmount = totalAmount.add(amount);

            System.out.println("第"+ (i+1) + "个人抢到的红包金额为：" + amount + "元，红包余额为：" + leftMoney + "元");
        }
        System.out.println("第"+ totalPeople + "个人抢到的红包金额为：" + leftMoney + "元，红包余额为：" + leftMoney + "元");

        // 累计金额
        totalAmount = totalAmount.add(leftMoney);
        System.out.println("验证发出的红包总金额："+ totalAmount + "元");
        System.out.println("================抢红包结束==================");
    }
}
